app.factory("googleGeocode", ["$http", "$q", "$exception", function ($http, $q, $exception) {
    function GoogleGeocodeService() {
    };

    GoogleGeocodeService.prototype = {
        getLocations: function (val) {
            var self = this;
            return $http.get('http://maps.googleapis.com/maps/api/geocode/json', {
                params: {
                    address: val,
                    sensor: false,
                    language: "fr",
                    region: "fr",
                    components: "country:FR"
                }
            }).then(function (res) {
                if (res.status != 200) throw new Error();
                if (res.data.status == "OVER_QUERY_LIMIT") throw new Error("Google Map over query limit.");

                var locations = res.data.results.reduce(function (previous, current) {
                    previous.push(self.createLocation(current));
                    return previous;
                }, []);
                return locations;
            }).catch(function (error) {
                $exception.show(error);
            });
        },
        parseComponents: function (place) {
            return place.address_components.reduce(function (previous, current) {
                previous[current.types[0]] = current.long_name;
                return previous;
            }, {});
        },
        createLocation: function (place) {
            var self = this;

            var components = self.parseComponents(place);

            var location = {
                address: place.formatted_address,
                street_number: components.street_number,
                route: components.route,
                city: components.locality,
                departement: components.administrative_area_level_2,
                postal_code: components.postal_code,
                loc: {
                    type: "Point",
                    coordinates: [place.geometry.location.lng, place.geometry.location.lat]
                }
            };
            return location;
        }
    }
    return new GoogleGeocodeService();
} ]);